home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 42 / Amiga Format AFCD42 (Issue 126, Aug 1999).iso / -serious- / programming / other / jikes / src / symbol.h < prev    next >
C/C++ Source or Header  |  1999-05-14  |  73KB  |  2,293 lines

  1. // $Id: symbol.h,v 1.11 1999/03/09 14:37:17 shields Exp $
  2. //
  3. // This software is subject to the terms of the IBM Jikes Compiler
  4. // License Agreement available at the following URL:
  5. // http://www.ibm.com/research/jikes.
  6. // Copyright (C) 1996, 1998, International Business Machines Corporation
  7. // and others.  All Rights Reserved.
  8. // You must accept the terms of that agreement to use this software.
  9. //
  10. #ifndef symbol_INCLUDED
  11. #define symbol_INCLUDED
  12.  
  13. #include "config.h"
  14. #include <assert.h>
  15. #include <stddef.h>
  16. #include <stdio.h>
  17. #include <sys/types.h>
  18. #include <sys/stat.h>
  19. #include <string.h>
  20. #include "code.h"
  21. #include "stream.h"
  22. #include "option.h"
  23. #include "lookup.h"
  24. #include "depend.h"
  25. #include "access.h"
  26. #include "tuple.h"
  27.  
  28. class Semantic;
  29. class SemanticEnvironment;
  30. class Ast;
  31. class AstCompilationUnit;
  32. class AstMethodDeclarator;
  33. class AstBlock;
  34. class AstList;
  35. class AstExpression;
  36. class AstVariableDeclarator;
  37. class ExpandedTypeTable;
  38. class ExpandedFieldTable;
  39. class ExpandedMethodTable;
  40. class SymbolTable;
  41. class SymbolSet;
  42. class Zip;
  43.  
  44. class PackageSymbol;
  45.  
  46. class PathSymbol : public Symbol
  47. public:
  48.     NameSymbol *name_symbol;
  49.     Zip *zipfile;
  50.  
  51.     PathSymbol(NameSymbol *);
  52.     virtual ~PathSymbol();
  53.  
  54.     virtual wchar_t *Name() { return name_symbol -> Name(); }
  55.     virtual int NameLength() { return name_symbol -> NameLength(); }
  56.     virtual NameSymbol *Identity() { return name_symbol; }
  57.     char *Utf8Name() { return (char *) (name_symbol -> Utf8_literal ? name_symbol -> Utf8_literal -> value : NULL); }
  58.     int Utf8NameLength() { return (name_symbol -> Utf8_literal ? name_symbol -> Utf8_literal -> length : 0); }
  59.  
  60.     inline bool IsZip() { return zipfile != NULL; }
  61.  
  62.     inline DirectorySymbol *RootDirectory() { return root_directory; }
  63.  
  64. private:
  65.     friend class SymbolTable;
  66.     DirectorySymbol *root_directory;
  67. };
  68.  
  69.  
  70. class DirectorySymbol : public Symbol
  71. public:
  72.     Symbol *owner;
  73.     NameSymbol *name_symbol;
  74.  
  75.     Tuple<DirectorySymbol *> subdirectories;
  76.  
  77.     DirectorySymbol(NameSymbol *, Symbol *);
  78.     virtual ~DirectorySymbol();
  79.  
  80.     virtual wchar_t *Name() { return name_symbol -> Name(); }
  81.     virtual int NameLength() { return name_symbol -> NameLength(); }
  82.     virtual NameSymbol *Identity() { return name_symbol; }
  83.     char *Utf8Name() { return (char *) (name_symbol -> Utf8_literal ? name_symbol -> Utf8_literal -> value : NULL); }
  84.     int Utf8NameLength() { return (name_symbol -> Utf8_literal ? name_symbol -> Utf8_literal -> length : 0); }
  85.  
  86.     DirectoryEntry *FindEntry(char *name, int len) { return (entries ? entries -> FindEntry(name, len) : (DirectoryEntry *) NULL); }
  87.  
  88. #ifdef WIN32_FILE_SYSTEM
  89.     DirectoryEntry *FindCaseInsensitiveEntry(char *name, int length)
  90.     {
  91.         return entries -> FindCaseInsensitiveEntry(name, length);
  92.     }
  93.  
  94.     void InsertEntry(char *name, int length)
  95.     {
  96.         DirectoryEntry *entry = entries -> InsertEntry((DirectorySymbol *) this, name, length);
  97.         entries -> InsertCaseInsensitiveEntry(entry);
  98.  
  99.         return;
  100.     }
  101. #endif
  102.  
  103.     PathSymbol *PathSym()
  104.     {
  105.         return (owner -> PathCast() ? (PathSymbol *) owner : ((DirectorySymbol *) owner) -> PathSym());
  106.     }
  107.  
  108.     inline bool IsZip() { return PathSym() -> IsZip(); }
  109.  
  110.     void SetDirectoryName();
  111.     inline char *DirectoryName()
  112.     {
  113.         if (! directory_name)
  114.             SetDirectoryName();
  115.         return directory_name;
  116.     }
  117.     inline int DirectoryNameLength()
  118.     {
  119.         if (! directory_name)
  120.             SetDirectoryName();
  121.         return directory_name_length;
  122.     }
  123.  
  124.     inline DirectorySymbol *InsertDirectorySymbol(NameSymbol *);
  125.     inline DirectorySymbol *InsertAndReadDirectorySymbol(NameSymbol *);
  126.     inline DirectorySymbol *FindDirectorySymbol(NameSymbol *);
  127.  
  128.     inline FileSymbol *InsertFileSymbol(NameSymbol *);
  129.     inline FileSymbol *FindFileSymbol(NameSymbol *);
  130.  
  131.     void ResetDirectory();
  132.  
  133. private:
  134.  
  135.     time_t mtime;
  136.  
  137.     void ReadDirectory();
  138.  
  139.     SymbolTable *table;
  140.     inline SymbolTable *Table();
  141.  
  142.     DirectoryTable *entries;
  143.     char *directory_name;
  144.     int directory_name_length;
  145. };
  146.  
  147.  
  148. class FileSymbol : public Symbol
  149. private:
  150.     enum FileKind
  151.     {
  152.         JAVA,
  153.         CLASS,
  154.         CLASS_ONLY
  155.     };
  156.  
  157.     DirectorySymbol *output_directory;
  158.     char *file_name;
  159.     int file_name_length;
  160.  
  161. public:
  162.     NameSymbol *name_symbol;
  163.     DirectorySymbol *directory_symbol;
  164.     PackageSymbol *package;
  165.     FileKind kind;
  166.  
  167.     //
  168.     // These fields are used for files in zip packages.
  169.     //
  170.     u4 uncompressed_size;
  171.     u4 date_time;
  172.     long offset;
  173.  
  174.     //
  175.     // This field holds the time of last data modification for a non-zip file
  176.     //
  177.     time_t mtime;
  178.  
  179.     LexStream *lex_stream;
  180.     AstCompilationUnit *compilation_unit;
  181.     Semantic *semantic;
  182.  
  183.     Tuple<TypeSymbol *> types;
  184.  
  185.     FileSymbol(NameSymbol *name_symbol_, NameSymbol *dirname_symbol = NULL) : name_symbol(name_symbol_),
  186.                                                                               output_directory(NULL),
  187.                                                                               directory_symbol(NULL),
  188.                                                                               package(NULL),
  189.                                                                               file_name(NULL),
  190.                                                                               mtime(0),
  191.                                                                               lex_stream(NULL),
  192.                                                                               compilation_unit(NULL),
  193.                                                                               semantic(NULL),
  194.                                                                               types(4)
  195.     {
  196.          Symbol::_kind = _FILE;
  197.     }
  198.  
  199.     virtual ~FileSymbol()
  200.     {
  201.         delete [] file_name;
  202.         delete lex_stream;
  203.     }
  204.  
  205.     FileSymbol *Clone()
  206.     {
  207.         FileSymbol *clone = new FileSymbol(name_symbol);
  208.  
  209.         clone -> kind = kind;
  210.         clone -> directory_symbol = directory_symbol;
  211.         clone -> mtime = mtime;
  212.  
  213.         return clone;
  214.     }
  215.  
  216.     virtual wchar_t *Name() { return name_symbol -> Name(); }
  217.     virtual int NameLength() { return name_symbol -> NameLength(); }
  218.     virtual NameSymbol *Identity() { return name_symbol; }
  219.     char *Utf8Name() { return (char *) (name_symbol -> Utf8_literal ? name_symbol -> Utf8_literal -> value : NULL); }
  220.     int Utf8NameLength() { return (name_symbol -> Utf8_literal ? name_symbol -> Utf8_literal -> length : 0); }
  221.  
  222.     inline void SetJava()       { kind = JAVA; }
  223.     inline void SetClass()      { kind = CLASS; }
  224.     inline void SetClassOnly()  { kind = CLASS_ONLY; }
  225.  
  226.     inline bool IsJava()       { return kind == JAVA; }
  227.     inline bool IsClass()      { return kind >= CLASS; }
  228.     inline bool IsClassOnly()  { return kind == CLASS_ONLY; }
  229.  
  230.     PathSymbol *PathSym()
  231.     {
  232.         return directory_symbol -> PathSym();
  233.     }
  234.     inline bool IsZip() { return PathSym() -> IsZip(); }
  235.     inline Zip *Zipfile() { return PathSym() -> zipfile; }
  236.  
  237.     static char *java_suffix;
  238.     static int java_suffix_length;
  239.     static char *class_suffix;
  240.     static int class_suffix_length;
  241.     static inline bool IsJavaSuffix(char *ptr);
  242.     static inline bool IsClassSuffix(char *ptr);
  243.  
  244.     inline char *FileName()
  245.     {
  246.         if (! file_name)
  247.             SetFileName();
  248.         return file_name;
  249.     }
  250.     inline int FileNameLength()
  251.     {
  252.         if (! file_name)
  253.             SetFileName();
  254.         return file_name_length;
  255.     }
  256.  
  257.     DirectorySymbol *OutputDirectory();
  258.  
  259.     void SetFileName();
  260.  
  261.     void CleanUp();
  262.  
  263.     void Reset()
  264.     {
  265.         CleanUp();
  266.  
  267.         delete [] file_name;
  268.         file_name = NULL;
  269.         types.Reset();
  270.     }
  271. };
  272.  
  273.  
  274. class FileLocation
  275. public:
  276.     wchar_t *location;
  277.  
  278.     FileLocation (LexStream *lex_stream, LexStream::TokenIndex token_index)
  279.     {
  280.         char *file_name = lex_stream -> FileName();
  281.         int length = lex_stream -> FileNameLength();
  282.         location = new wchar_t[length + 13];
  283.         for (int i = 0; i < length; i++) {
  284.             location[i] = (wchar_t) file_name[i];
  285.         }
  286.         location[length++] = U_COLON;
  287.  
  288.         char str[13];
  289.         sprintf(str, "%i", lex_stream -> Line(token_index));
  290.         for (int j = 0; str[j]; j++)
  291.             location[length++] = str[j];
  292.         location[length] = U_NULL;
  293.  
  294.         return;
  295.     }
  296.  
  297.     FileLocation (FileSymbol *file_symbol)
  298.     {
  299.         char *file_name = file_symbol -> FileName();
  300.         int length = file_symbol -> FileNameLength();
  301.         location = new wchar_t[length + 13];
  302.         for (int i = 0; i < length; i++) {
  303.             location[i] = (wchar_t) file_name[i];
  304.         }
  305.         location[length] = U_NULL;
  306.  
  307.         return;
  308.     }
  309.  
  310.     ~FileLocation()
  311.     {
  312.         delete [] location;
  313.     }
  314. };
  315.  
  316.  
  317. class PackageSymbol : public Symbol
  318. public:
  319.     Tuple<DirectorySymbol *> directory;
  320.     PackageSymbol *owner;
  321.  
  322.     PackageSymbol(NameSymbol *name_symbol_, PackageSymbol *owner_) : name_symbol(name_symbol_),
  323.                                                                      directory(4),
  324.                                                                      owner(owner_),
  325.                                                                      package_name(NULL),
  326.                                                                      table(NULL)
  327.     {
  328.         Symbol::_kind = PACKAGE;
  329.     }
  330.  
  331.     virtual ~PackageSymbol();
  332.  
  333.     virtual wchar_t *Name() { return name_symbol -> Name(); }
  334.     virtual int NameLength() { return name_symbol -> NameLength(); }
  335.     virtual NameSymbol *Identity() { return name_symbol; }
  336.     char *Utf8Name() { return (char *) (name_symbol -> Utf8_literal ? name_symbol -> Utf8_literal -> value : NULL); }
  337.     int Utf8NameLength() { return (name_symbol -> Utf8_literal ? name_symbol -> Utf8_literal -> length : 0); }
  338.  
  339.     void SetPackageName();
  340.     wchar_t *PackageName()
  341.     {
  342.         if (! package_name)
  343.             SetPackageName();
  344.         return package_name;
  345.     }
  346.     int PackageNameLength()
  347.     {
  348.         if (! package_name)
  349.             SetPackageName();
  350.         return package_name_length;
  351.     }
  352.  
  353.     inline PackageSymbol *FindPackageSymbol(NameSymbol *);
  354.     inline PackageSymbol *InsertPackageSymbol(NameSymbol *);
  355.  
  356.     inline TypeSymbol *FindTypeSymbol(NameSymbol *);
  357.     inline TypeSymbol *InsertSystemTypeSymbol(NameSymbol *);
  358.     inline TypeSymbol *InsertOuterTypeSymbol(NameSymbol *);
  359.     inline void DeleteTypeSymbol(TypeSymbol *);
  360.  
  361. private:
  362.  
  363.     NameSymbol *name_symbol;
  364.     SymbolTable *table;
  365.     inline SymbolTable *Table();
  366.  
  367.     wchar_t *package_name;
  368.     int package_name_length;
  369. };
  370.  
  371.  
  372. class MethodSymbol : public Symbol, public AccessFlags
  373. public:
  374.     Ast *method_or_constructor_declaration; // AstMethodDeclaration or AstConstructorDeclaration
  375.     NameSymbol *name_symbol;
  376.     TypeSymbol *containing_type;
  377.     BlockSymbol *block_symbol;
  378.     MethodSymbol *next_method;
  379.     Utf8LiteralValue *signature;
  380.  
  381.     //
  382.     // If this method is a method that is generated in order to process initializer
  383.     // blocks contained in the body of a class, it needs to know the set of
  384.     // constructors that might invoke it in order to figure out which exceptions
  385.     // can be safely thrown within an initializer block.
  386.     //
  387.     int NumInitializerConstructors()
  388.     {
  389.         return (initializer_constructors ? initializer_constructors -> Length() : 0);
  390.     }
  391.     MethodSymbol *InitializerConstructor(int i)
  392.     {
  393.         return (*initializer_constructors)[i];
  394.     }
  395.     void AddInitializerConstructor(MethodSymbol *method)
  396.     {
  397.         if (! initializer_constructors)
  398.             initializer_constructors = new Tuple<MethodSymbol *>(8);
  399.         initializer_constructors -> Next() = method;
  400.     }
  401.  
  402.     int max_block_depth,
  403.         constant_pool_index,
  404.         constant_pool_class;
  405.  
  406.     //
  407.     // If the method in question is a private member, we may need to construct
  408.     // another method that allows it to be accessed by inner classes. 
  409.     //
  410.     MethodSymbol *read_method;
  411.  
  412.     //
  413.     // If this method is a method that permits access to a private member of an
  414.     // enclosing type then accessed_member identifies the member in question.
  415.     //
  416.     Symbol *accessed_member;
  417.  
  418.     virtual wchar_t *Name() { return name_symbol -> Name(); }
  419.     virtual int NameLength() { return name_symbol -> NameLength(); }
  420.     virtual NameSymbol *Identity() { return name_symbol; }
  421.     char *Utf8Name() { return (char *) (name_symbol -> Utf8_literal ? name_symbol -> Utf8_literal -> value : NULL); }
  422.     int Utf8NameLength() { return (name_symbol -> Utf8_literal ? name_symbol -> Utf8_literal -> length : 0); }
  423.  
  424.     MethodSymbol(NameSymbol *name_symbol_) : method_or_constructor_declaration(NULL),
  425.                                              name_symbol(name_symbol_),
  426.                                              external_name_symbol(NULL),
  427.                                              containing_type(NULL),
  428.                                              block_symbol(NULL),
  429.                                              next_method(NULL),
  430.                                              signature(NULL),
  431.                                              type_(NULL),
  432.                                              status(0),
  433.                                              header(NULL),
  434.                                              max_block_depth(1), // there must be at least one block in a method
  435.                                                                  // this default is useful for default constructors.
  436.                                              constant_pool_index(0),
  437.                                              constant_pool_class(0),
  438.                                              local_constructor(NULL),
  439.                                              read_method(NULL),
  440.                                              accessed_member(NULL),
  441.                                              formal_parameters(NULL),
  442.                                              throws(NULL),
  443.                                              throws_signatures(NULL),
  444.                                              initializer_constructors(NULL)
  445.     {
  446.         Symbol::_kind = METHOD;
  447.     }
  448.  
  449.     virtual ~MethodSymbol();
  450.  
  451.     bool IsFinal();
  452.  
  453.     bool IsTyped()
  454.     {
  455.         return type_ != NULL;
  456.     }
  457.  
  458.     void SetType(TypeSymbol *_type)
  459.     {
  460.         type_ = _type;
  461.     }
  462.  
  463.     void ProcessMethodSignature(Semantic *, LexStream::TokenIndex);
  464.     void ProcessMethodThrows(Semantic *, LexStream::TokenIndex);
  465.  
  466.     TypeSymbol *Type(Semantic *sem = NULL, LexStream::TokenIndex tok = 0)
  467.     {
  468.         if (! type_)
  469.             ProcessMethodSignature(sem, tok);
  470. assert(type_);
  471.         return type_;
  472.     }
  473.  
  474.     int NumFormalParameters(Semantic *sem = NULL, LexStream::TokenIndex tok = 0)
  475.     {
  476.         if (! type_)
  477.             ProcessMethodSignature(sem, tok);
  478. assert(type_);
  479.         return (formal_parameters ? formal_parameters -> Length() : 0);
  480.     }
  481.     VariableSymbol *FormalParameter(int i)
  482.     {
  483.         return (*formal_parameters)[i];
  484.     }
  485.     void AddFormalParameter(VariableSymbol *variable)
  486.     {
  487.         if (! formal_parameters)
  488.             formal_parameters = new Tuple<VariableSymbol *>(8);
  489.         formal_parameters -> Next() = variable;
  490.     }
  491.  
  492.     int NumThrows(Semantic *sem = NULL, LexStream::TokenIndex tok = 0)
  493.     {
  494.         if (throws_signatures)
  495.             ProcessMethodThrows(sem, tok);
  496. assert(! throws_signatures);
  497.         return (throws ? throws -> Length() : 0);
  498.     }
  499.     TypeSymbol *Throws(int i)
  500.     {
  501.         return (*throws)[i];
  502.     }
  503.     void AddThrows(TypeSymbol *exception)
  504.     {
  505.         if (! throws)
  506.             throws = new Tuple<TypeSymbol *>(8);
  507.         throws -> Next() = exception;
  508.     }
  509.  
  510.     int NumThrowsSignatures()
  511.     {
  512.         return (throws_signatures ? throws_signatures -> Length() : 0);
  513.     }
  514.     char *ThrowsSignature(int i)
  515.     {
  516.         return (*throws_signatures)[i];
  517.     }
  518.     void AddThrowsSignature(char *signature_, int length)
  519.     {
  520.         char *signature = new char[length + 1];
  521.         strncpy(signature, signature_, length);
  522.         signature[length] = U_NULL;
  523.  
  524.         if (! throws_signatures)
  525.             throws_signatures = new Tuple<char *>(8);
  526.         throws_signatures -> Next() = signature;
  527.     }
  528.  
  529.     void SetGeneratedLocalConstructor(MethodSymbol *base_method)
  530.     {
  531. assert(! base_method -> local_constructor);
  532.        base_method -> local_constructor = this;
  533.        this -> local_constructor = base_method;
  534.     }
  535.     bool IsGeneratedLocalConstructor() { return ((local_constructor != NULL) && (this -> external_name_symbol == NULL)); }
  536.     MethodSymbol *LocalConstructor()  { return local_constructor; }
  537.  
  538.     void SetExternalIdentity(NameSymbol *external_name_symbol_) { external_name_symbol = external_name_symbol_; }
  539.     NameSymbol *ExternalIdentity()
  540.     {
  541.         return (external_name_symbol ? external_name_symbol : name_symbol);
  542.     }
  543.     wchar_t *ExternalName()
  544.     {
  545.         return (external_name_symbol ? external_name_symbol -> Name() : name_symbol -> Name());
  546.     }
  547.     int ExternalNameLength()
  548.     {
  549.         return (external_name_symbol ? external_name_symbol -> NameLength() : name_symbol -> NameLength());
  550.     }
  551.     char *ExternalUtf8Name()
  552.     {
  553.         return (char *) (external_name_symbol ? external_name_symbol -> Utf8_literal -> value
  554.                                               : (name_symbol -> Utf8_literal ? name_symbol -> Utf8_literal -> value : NULL));
  555.     }
  556.     int ExternalUtf8NameLength()
  557.     {
  558.         return (external_name_symbol ? (external_name_symbol -> Utf8_literal ? external_name_symbol -> Utf8_literal -> length : 0)
  559.                                      : (name_symbol -> Utf8_literal ? name_symbol -> Utf8_literal -> length : 0));
  560.     }
  561.  
  562.     void SetFlags(AccessFlags variable_access) { access_flags = variable_access.access_flags; }
  563.     void SetContainingType(TypeSymbol *containing_type_) { containing_type = containing_type_; }
  564.     void SetBlockSymbol(BlockSymbol *block_symbol_) { block_symbol = block_symbol_; }
  565.     void SetSignature(Control &, VariableSymbol * = NULL);
  566.     void SetSignature(Utf8LiteralValue *signature_) { signature = signature_; }
  567.     char *SignatureString() { return signature -> value; }
  568.     wchar_t *Header(Semantic * = NULL, LexStream::TokenIndex = 0);
  569.  
  570.     void CleanUp();
  571.  
  572.     void MarkSynthetic() { status |= (unsigned char) 0x08; }
  573.     bool IsSynthetic()   { return status & (unsigned char) 0x08; }
  574.  
  575. private:
  576.     NameSymbol *external_name_symbol;
  577.  
  578.     unsigned char status;
  579.     wchar_t *header;
  580.  
  581.     TypeSymbol *type_;
  582.     Tuple<VariableSymbol *> *formal_parameters;
  583.     Tuple<TypeSymbol *> *throws;
  584.     Tuple<char *> *throws_signatures;
  585.     Tuple<MethodSymbol *> *initializer_constructors;
  586.  
  587.     //
  588.     // If the method in question is a constructor of a local type, we may need to construct
  589.     // another constructor that accepts extra local parameters.
  590.     //
  591.     MethodSymbol *local_constructor;
  592.  
  593.     bool ACC_FINAL()
  594.     {
  595. assert(! "use the ACC_FINAL() flag on a method symbol. Use the function IsFinal() instead");
  596.         return false;
  597.     }
  598. };
  599.  
  600.  
  601. class TypeSymbol : public Symbol, public AccessFlags
  602. public:
  603.     SemanticEnvironment *semantic_environment;
  604.     Ast *declaration;  // AstClassDeclaration or AstInterfaceDeclaration
  605.     FileSymbol *file_symbol;
  606.     FileLocation *file_location;
  607.     NameSymbol *name_symbol;
  608.     Symbol *owner;
  609.     TypeSymbol *outermost_type; // An nested class identifies the outer most type that contains it.
  610.                                 // If a class is not nested then it identifies itself as its outer
  611.                                 // most type.
  612.     TypeSymbol *super;
  613.     TypeSymbol *base_type; // indicates the base type (type of elements in the last dimension) of an array
  614.                            // For a normal type base_type is NULL. If base_type is a "bad" type it points
  615.                            // to itsself (this).
  616.     int index,             // The first two variables is used in TypeCycleChecker to determine if this class or interface
  617.                            // forms a cycle in its "extends" or "implements" relationship.
  618.         incremental_index; // This variable is used in TypeCycleChecker to determine which types (files)
  619.                            // need to be recompiled based on the "dependent" relationship.
  620.  
  621.     int NumLocalConstructorCallEnvironments() { return (local_constructor_call_environments ? local_constructor_call_environments -> Length() : 0); }
  622.     SemanticEnvironment *&LocalConstructorCallEnvironment(int i) { return (*local_constructor_call_environments)[i]; }
  623.     void AddLocalConstructorCallEnvironment(SemanticEnvironment *environment)
  624.     {
  625.         if (! local_constructor_call_environments)
  626.             local_constructor_call_environments = new Tuple<SemanticEnvironment *>(8);
  627.         local_constructor_call_environments -> Next() = environment;
  628.     }
  629.  
  630.     int NumPrivateAccessMethods() { return (private_access_methods ? private_access_methods -> Length() : 0); }
  631.     MethodSymbol *&PrivateAccessMethod(int i) { return (*private_access_methods)[i]; }
  632.     void AddPrivateAccessMethod(MethodSymbol *method_symbol)
  633.     {
  634.         if (! private_access_methods)
  635.             private_access_methods = new Tuple<MethodSymbol *>(8);
  636.         private_access_methods -> Next() = method_symbol;
  637.     }
  638.  
  639.     int NumPrivateAccessConstructors() { return (private_access_constructors ? private_access_constructors -> Length() : 0); }
  640.     MethodSymbol *&PrivateAccessConstructor(int i) { return (*private_access_constructors)[i]; }
  641.     void AddPrivateAccessConstructor(MethodSymbol *constructor_symbol)
  642.     {
  643.         if (! private_access_constructors)
  644.             private_access_constructors = new Tuple<MethodSymbol *>(8);
  645.         private_access_constructors -> Next() = constructor_symbol;
  646.     }
  647.  
  648.     int NumConstructorParameters() { return (constructor_parameters ? constructor_parameters -> Length() : 0); }
  649.     VariableSymbol *&ConstructorParameter(int i) { return (*constructor_parameters)[i]; }
  650.     void AddConstructorParameter(VariableSymbol *variable_symbol)
  651.     {
  652.         if (! constructor_parameters)
  653.             constructor_parameters = new Tuple<VariableSymbol *>(8);
  654.         constructor_parameters -> Next() = variable_symbol;
  655.     }
  656.  
  657.     int NumGeneratedConstructors() { return (generated_constructors ? generated_constructors -> Length() : 0); }
  658.     MethodSymbol *&GeneratedConstructor(int i) { return (*generated_constructors)[i]; }
  659.     void AddGeneratedConstructor(MethodSymbol *constructor_symbol)
  660.     {
  661.         if (! generated_constructors)
  662.             generated_constructors = new Tuple<MethodSymbol *>(8);
  663.         generated_constructors -> Next() = constructor_symbol;
  664.     }
  665.  
  666.     int NumEnclosingInstances() { return (enclosing_instances ? enclosing_instances -> Length() : 0); }
  667.     VariableSymbol *&EnclosingInstance(int i) { return (*enclosing_instances)[i]; }
  668.     void AddEnclosingInstance(VariableSymbol *instance_symbol)
  669.     {
  670.         if (! enclosing_instances)
  671.             enclosing_instances = new Tuple<VariableSymbol *>(8);
  672.         enclosing_instances -> Next() = instance_symbol;
  673.     }
  674.  
  675.     int NumClassLiterals() { return (class_literals ? class_literals -> Length() : 0); }
  676.     VariableSymbol *&ClassLiteral(int i) { return (*class_literals)[i]; }
  677.     void AddClassLiteral(VariableSymbol *literal_symbol)
  678.     {
  679.         if (! class_literals)
  680.             class_literals = new Tuple<VariableSymbol *>(8);
  681.         class_literals -> Next() = literal_symbol;
  682.     }
  683.  
  684.     int NumNestedTypes() { return (nested_types ? nested_types -> Length() : 0); }
  685.     TypeSymbol *&NestedType(int i) { return (*nested_types)[i]; }
  686.     void AddNestedType(TypeSymbol *type_symbol)
  687.     {
  688.         if (! nested_types)
  689.             nested_types = new Tuple<TypeSymbol *>(8);
  690.         nested_types -> Next() = type_symbol;
  691.     }
  692.  
  693.     int NumInterfaces() { return (interfaces ? interfaces -> Length() : 0); }
  694.     void ResetInterfaces()
  695.     {
  696.         delete interfaces;
  697.         interfaces = NULL;
  698.     }
  699.     TypeSymbol *Interface(int i) { return (*interfaces)[i]; }
  700.     void AddInterface(TypeSymbol *type_symbol)
  701.     {
  702.         if (! interfaces)
  703.             interfaces = new Tuple<TypeSymbol *>(8);
  704.         interfaces -> Next() = type_symbol;
  705.     }
  706.  
  707.     int num_anonymous_types() { return (anonymous_types ? anonymous_types -> Length() : 0); }
  708.     TypeSymbol *&AnonymousType(int i) { return (*anonymous_types)[i]; }
  709.     void AddAnonymousType(TypeSymbol *type_symbol)
  710.     {
  711.         if (! anonymous_types)
  712.             anonymous_types = new Tuple<TypeSymbol *>(8);
  713.         anonymous_types -> Next() = type_symbol;
  714.     }
  715.     void DeleteAnonymousTypes();
  716.  
  717.     SymbolSet *local,
  718.               *non_local;
  719.  
  720.     SymbolSet *supertypes_closure,
  721.               *subtypes,
  722.               *subtypes_closure,
  723.               *innertypes_closure;
  724.  
  725.     SymbolSet *dependents,
  726.               *parents,
  727.               *dependents_closure,  // processed in cycle.cpp
  728.               *parents_closure;     // processed in cycle.cpp
  729.  
  730.     int pool_index; // index of element in symbol_pool (in the relevant symbol table) that points to this type
  731.  
  732.     Utf8LiteralValue *signature;
  733.     Utf8LiteralValue *fully_qualified_name;
  734.  
  735.     ExpandedTypeTable *expanded_type_table;
  736.     ExpandedFieldTable *expanded_field_table;
  737.     ExpandedMethodTable *expanded_method_table;
  738.  
  739.     int num_dimensions;
  740.  
  741.     MethodSymbol *static_initializer_method;
  742.     MethodSymbol *block_initializer_method;
  743.  
  744.     virtual wchar_t *Name() { return name_symbol -> Name(); }
  745.     virtual int NameLength() { return name_symbol -> NameLength(); }
  746.     virtual NameSymbol *Identity() { return name_symbol; }
  747.     char *Utf8Name() { return (char *) (name_symbol -> Utf8_literal ? name_symbol -> Utf8_literal -> value : NULL); }
  748.     int Utf8NameLength() { return (name_symbol -> Utf8_literal ? name_symbol -> Utf8_literal -> length : 0); }
  749.  
  750.     void SetExternalIdentity(NameSymbol *external_name_symbol_) { external_name_symbol = external_name_symbol_; }
  751.     NameSymbol *ExternalIdentity()
  752.     {
  753.         return (external_name_symbol ? external_name_symbol : name_symbol);
  754.     }
  755.     wchar_t *ExternalName()
  756.     {
  757.         return (external_name_symbol ? external_name_symbol -> Name() : name_symbol -> Name());
  758.     }
  759.     int ExternalNameLength()
  760.     {
  761.         return (external_name_symbol ? external_name_symbol -> NameLength() : name_symbol -> NameLength());
  762.     }
  763.     char *ExternalUtf8Name()
  764.     {
  765.         return (char *) (external_name_symbol ? external_name_symbol -> Utf8_literal -> value
  766.                                               : (name_symbol -> Utf8_literal ? name_symbol -> Utf8_literal -> value : NULL));
  767.     }
  768.     int ExternalUtf8NameLength()
  769.     {
  770.         return (external_name_symbol ? (external_name_symbol -> Utf8_literal ? external_name_symbol -> Utf8_literal -> length : 0)
  771.                                      : (name_symbol -> Utf8_literal ? name_symbol -> Utf8_literal -> length : 0));
  772.     }
  773.  
  774.     TypeSymbol(NameSymbol *);
  775.     virtual ~TypeSymbol();
  776.  
  777.     void ProcessTypeHeaders();
  778.     void ProcessMembers();
  779.     void CompleteSymbolTable();
  780.     void ProcessExecutableBodies();
  781.     void RemoveCompilationReferences();
  782.  
  783.     NameSymbol *GetThisName(Control &, int);
  784.  
  785.     VariableSymbol *FindThis(int k)
  786.     {
  787. assert(IsInner());
  788. assert(NumConstructorParameters() > 0);
  789.         return (k == 0 ? ConstructorParameter(0)
  790.                        : (VariableSymbol *) (NumEnclosingInstances() > k ? EnclosingInstance(k) : NULL));
  791.     }
  792.     VariableSymbol *InsertThis(int k);
  793.  
  794.     TypeSymbol *FindOrInsertClassLiteralClass(LexStream::TokenIndex);
  795.     TypeSymbol *ClassLiteralClass()
  796.     {
  797.         return class_literal_class;
  798.     }
  799.     MethodSymbol *FindOrInsertClassLiteralMethod(Control &);
  800.     MethodSymbol *ClassLiteralMethod()
  801.     {
  802.         return class_literal_method;
  803.     }
  804.     Utf8LiteralValue *FindOrInsertClassLiteralName(Control &);
  805.     Utf8LiteralValue *ClassLiteralName()
  806.     {
  807.         return class_literal_name;
  808.     }
  809.     VariableSymbol *FindOrInsertClassLiteral(TypeSymbol *);
  810.     VariableSymbol *FindOrInsertLocalShadow(VariableSymbol *);
  811.  
  812.     static MethodSymbol *GetReadAccessMethod(MethodSymbol *);
  813.     static MethodSymbol *GetReadAccessMethod(VariableSymbol *);
  814.     static MethodSymbol *GetWriteAccessMethod(VariableSymbol *);
  815.  
  816.     bool IsArray() { return (num_dimensions > 0); }
  817.  
  818.     void SetOwner(Symbol *owner_) { owner = owner_; }
  819.     bool IsOwner(TypeSymbol *type)
  820.     {
  821.         Symbol *sym = type -> owner;
  822.         while (! sym -> PackageCast())
  823.         {
  824.             if (sym == this)
  825.                 return true;
  826.  
  827.             MethodSymbol *method = sym -> MethodCast();
  828.             sym = (method ? method -> containing_type : ((TypeSymbol *) sym) -> owner);
  829.         }
  830.  
  831.         return false;
  832.     }
  833.  
  834.     TypeSymbol *ContainingType()
  835.     {
  836.         if (owner)
  837.         {
  838.             TypeSymbol *type = owner -> TypeCast();
  839.             if (type)
  840.                 return type;
  841.             MethodSymbol *method = owner -> MethodCast();
  842.             if (method)
  843.                 return method -> containing_type;
  844.         }
  845.  
  846.         return NULL;
  847.     }
  848.  
  849.     bool CanAccess(TypeSymbol *);
  850.  
  851.     bool HasProtectedAccessTo(TypeSymbol *);
  852.  
  853.     bool IsSubclass(TypeSymbol *super_class)
  854.     {
  855.         return (this == super_class ? true : (super == NULL ? false : super -> IsSubclass(super_class)));
  856.     }
  857.  
  858.     bool IsSubinterface(TypeSymbol *super_interface)
  859.     {
  860.         if (this == super_interface)
  861.             return true;
  862.         for (int i = 0; i < NumInterfaces(); i++)
  863.         {
  864.             if (Interface(i) -> IsSubinterface(super_interface))
  865.                 return true;
  866.         }
  867.         return false;
  868.     }
  869.  
  870.     bool Implements(TypeSymbol *inter)
  871.     {
  872.         for (int i = 0; i < NumInterfaces(); i++)
  873.         {
  874.             if (Interface(i) -> IsSubinterface(inter))
  875.                 return true;
  876.         }
  877.         return (this -> super ? this -> super -> Implements(inter) : false);
  878.     }
  879.  
  880.     wchar_t *FileLoc()
  881.     {
  882.         return (wchar_t *) (file_location ? file_location -> location : NULL);
  883.     }
  884.  
  885.     void SetLocation();
  886.  
  887.     TypeSymbol *GetArrayType(Semantic *, int);
  888.  
  889.     TypeSymbol *ArraySubtype()
  890.     {
  891.         return this -> base_type -> Array(this -> num_dimensions - 1);
  892.     }
  893.  
  894.     void SetSignature(Control &);
  895.     void SetSignature(Utf8LiteralValue *signature_) { signature = signature_; }
  896.     char *SignatureString() { return signature -> value; }
  897.  
  898.     void SetClassLiteralName(Utf8LiteralValue *class_literal_name_) { class_literal_name = class_literal_name_; }
  899.  
  900.     PackageSymbol *ContainingPackage() { return outermost_type -> owner -> PackageCast(); }
  901.  
  902.     void SetFlags(AccessFlags variable_access) { access_flags = variable_access.access_flags; }
  903.  
  904.     bool IsNestedIn(TypeSymbol *);
  905.  
  906.     bool IsNested() { return outermost_type != this; }
  907.  
  908.     bool IsTopLevel() { return (! IsNested()) || this -> ACC_STATIC(); }
  909.  
  910.     bool IsInner() { return (! IsTopLevel()); }
  911.  
  912.     bool IsLocal()
  913.     {
  914.         for (Symbol *sym = owner; ! sym -> PackageCast(); sym = ((TypeSymbol *) sym) -> owner)
  915.         {
  916.             if (sym -> MethodCast())
  917.                 return true;
  918.         }
  919.  
  920.         return false;
  921.     }
  922.  
  923.     inline char *ClassName()
  924.     {
  925.         if (! class_name)
  926.             SetClassName();
  927.         return class_name;
  928.     }
  929.  
  930.     void MarkConstructorMembersProcessed() { status |= (unsigned short) 0x0001; }
  931.     bool ConstructorMembersProcessed() { return status & (unsigned short) 0x0001; }
  932.  
  933.     void MarkMethodMembersProcessed() { status |= (unsigned short) 0x0002; }
  934.     bool MethodMembersProcessed() { return status & (unsigned short) 0x0002; }
  935.  
  936.     void MarkFieldMembersProcessed() { status |= (unsigned short) 0x0004; }
  937.     bool FieldMembersProcessed() { return status & (unsigned short) 0x0004; }
  938.  
  939.     void MarkLocalClassProcessingCompleted() { status |= (unsigned short) 0x0008; }
  940.     bool LocalClassProcessingCompleted() { return status & (unsigned short) 0x0008; }
  941.  
  942.     void MarkSourcePending() { status |= (unsigned short) 0x0010; }
  943.     void MarkSourceNoLongerPending() { status &= (~ ((unsigned short) 0x0010)); }
  944.     bool SourcePending() { return status & (unsigned short) 0x0010; }
  945.  
  946.     void MarkAnonymous() { status |= (unsigned short) 0x0020; }
  947.     bool Anonymous() { return status & (unsigned short) 0x0020; }
  948.  
  949.     void MarkHeaderProcessed() { status |= (unsigned short) 0x0040; }
  950.     bool HeaderProcessed() { return status & (unsigned short) 0x0040; }
  951.  
  952.     void MarkPrimitive() { status |= (unsigned short) 0x0080; }
  953.     bool Primitive()     { return status & (unsigned short) 0x0080; }
  954.  
  955.     void MarkBad()
  956.     {
  957.         SetACC_PUBLIC();
  958.  
  959.         status |= (unsigned short) 0x0100;
  960.  
  961.         MarkHeaderProcessed();
  962.         MarkConstructorMembersProcessed();
  963.         MarkMethodMembersProcessed();
  964.         MarkFieldMembersProcessed();
  965.         MarkLocalClassProcessingCompleted();
  966.         MarkSourceNoLongerPending();
  967.  
  968.         return;
  969.     }
  970.     bool Bad() { return status & (unsigned short) 0x0100; }
  971.  
  972.     void MarkCircular()
  973.     {
  974.         status |= (unsigned short) 0x0200;
  975.         MarkBad();
  976.         return;
  977.     }
  978.     void MarkNonCircular() { status &= (~ ((unsigned short) 0x0200)); }
  979.     bool Circular() { return status & (unsigned short) 0x0200; }
  980.  
  981.     void ProcessNestedTypeSignatures(Semantic *, LexStream::TokenIndex);
  982.  
  983.     bool NestedTypesProcessed() { return nested_type_signatures == NULL; }
  984.  
  985.     int NumNestedTypeSignatures()
  986.     {
  987.         return (nested_type_signatures ? nested_type_signatures -> Length() : 0);
  988.     }
  989.     char *NestedTypeSignature(int i)
  990.     {
  991.         return (*nested_type_signatures)[i];
  992.     }
  993.     void AddNestedTypeSignature(char *signature_, int length)
  994.     {
  995.         char *signature = new char[length + 1];
  996.         strncpy(signature, signature_, length);
  997.         signature[length] = U_NULL;
  998.  
  999.         if (! nested_type_signatures)
  1000.             nested_type_signatures = new Tuple<char *>(8);
  1001.         nested_type_signatures -> Next() = signature;
  1002.     }
  1003.  
  1004.     inline void SetSymbolTable(int);
  1005.     inline SymbolTable *Table();
  1006.  
  1007.     int NumVariableSymbols();
  1008.     VariableSymbol *VariableSym(int);
  1009.  
  1010.     int NumMethodSymbols();
  1011.     MethodSymbol *MethodSym(int);
  1012.  
  1013.     int NumTypeSymbols();
  1014.     TypeSymbol *TypeSym(int);
  1015.  
  1016.     inline TypeSymbol *InsertAnonymousTypeSymbol(NameSymbol *);
  1017.     inline TypeSymbol *FindTypeSymbol(NameSymbol *);
  1018.     inline TypeSymbol *InsertNestedTypeSymbol(NameSymbol *);
  1019.     inline MethodSymbol *FindConstructorSymbol();
  1020.     inline MethodSymbol *InsertConstructorSymbol(NameSymbol *);
  1021.     inline void InsertConstructorSymbol(MethodSymbol *);
  1022.     inline MethodSymbol *FindMethodSymbol(NameSymbol *);
  1023.     inline VariableSymbol *FindVariableSymbol(NameSymbol *);
  1024.     inline VariableSymbol *InsertVariableSymbol(NameSymbol *);
  1025.     inline void InsertVariableSymbol(VariableSymbol *);
  1026.  
  1027.     inline MethodSymbol *InsertMethodSymbol(NameSymbol *);
  1028.     inline void InsertMethodSymbol(MethodSymbol *);
  1029.     inline MethodSymbol *Overload(MethodSymbol *);
  1030.     inline void Overload(MethodSymbol *, MethodSymbol *);
  1031.     inline MethodSymbol *LocalConstructorOverload(MethodSymbol *);
  1032.     MethodSymbol *FindOverloadMethod(MethodSymbol *, AstMethodDeclarator *);
  1033.  
  1034.     inline void CompressSpace();
  1035.  
  1036. private:
  1037.     NameSymbol *external_name_symbol;
  1038.  
  1039.     SymbolTable *table;
  1040.  
  1041.     unsigned short status;
  1042.  
  1043.     PackageSymbol *package;
  1044.     char *class_name;
  1045.  
  1046.     void SetClassName();
  1047.  
  1048.     TypeSymbol *class_literal_class;
  1049.     MethodSymbol *class_literal_method;
  1050.     Utf8LiteralValue *class_literal_name;
  1051.  
  1052.     //
  1053.     // For a local type, when we first encounter an embedded call
  1054.     // to one of its constructors or a constructor of one of its inner
  1055.     // types, either via a ClassInstanceCreation or an ExplicitConstructorInvocation,
  1056.     // we record it and resolve it after we have computed all necessary 
  1057.     // information about the type and its inner types.
  1058.     //
  1059.     Tuple<SemanticEnvironment *> *local_constructor_call_environments;
  1060.  
  1061.     //
  1062.     // When an inner class tries to access a private member of one of its enclosing
  1063.     // classes, one (or two) access method(s) to read (and/or write) the private member
  1064.     // is (are) generated.
  1065.     //
  1066.     Tuple<MethodSymbol *> *private_access_methods;
  1067.     Tuple<MethodSymbol *> *private_access_constructors;
  1068.  
  1069.     //
  1070.     // For an accessible inner class the first elememt in this array
  1071.     // identifies the "this$0" pointer of the containing type. For a local
  1072.     // class, in addition to the this$0 pointer (if it is needed), all local
  1073.     // variables that are referred to in the local type are passed as argument
  1074.     // to the local type and copied in the constructor into a local field. These
  1075.     // local variables are stored in constructor_parameters.
  1076.     //
  1077.     // The array enclosing_instances is there for optimization purposes.
  1078.     // If this type is deeply nested within several other types and it makes
  1079.     // references to members in the enclosing types, then it might
  1080.     // be useful to keep a reference to each of these enclosing
  1081.     // instances in the form of this$0, this$1, this$2, ...
  1082.     //
  1083.     // The array class_identities is used to store static variables of type Class
  1084.     // that contain the proper value for a given type.
  1085.     //
  1086.     Tuple<VariableSymbol *> *constructor_parameters;
  1087.     Tuple<MethodSymbol *> *generated_constructors;
  1088.     Tuple<VariableSymbol *> *enclosing_instances;
  1089.     Tuple<VariableSymbol *> *class_literals;
  1090.  
  1091.     Tuple<char *> *nested_type_signatures;
  1092.  
  1093.     //
  1094.     // The inner types that appear immediately within this type in the order
  1095.     // in which they should be processed (compiled).
  1096.     Tuple<TypeSymbol *> *nested_types;
  1097.  
  1098.     //
  1099.     // The interfaces that were declared in the header of the type.
  1100.     //
  1101.     Tuple<TypeSymbol *> *interfaces;
  1102.  
  1103.     //
  1104.     // The anonymous types that were declared in this type.
  1105.     //
  1106.     Tuple<TypeSymbol *> *anonymous_types;
  1107.  
  1108.     //
  1109.     // The arrays of this type that were declared.
  1110.     //
  1111.     Tuple<TypeSymbol *> *array;
  1112.     inline int NumArrays()
  1113.     {
  1114.         return (array ? array -> Length() : 0);
  1115.     }
  1116.     inline TypeSymbol *Array(int i)
  1117.     {
  1118.         return (*array)[i];
  1119.     }
  1120.     inline void AddArrayType(TypeSymbol *type_symbol)
  1121.     {
  1122.         if (! array)
  1123.             array = new Tuple<TypeSymbol *>(4);
  1124.         array -> Next() = type_symbol;
  1125.     }    
  1126. };
  1127.  
  1128.  
  1129. class VariableSymbol : public Symbol, public AccessFlags
  1130. public:
  1131.     Ast *declarator;
  1132.  
  1133.     NameSymbol *name_symbol;
  1134.     Symbol     *owner;
  1135.     LiteralValue *initial_value;
  1136.     int constant_pool_index,
  1137.         constant_pool_class,
  1138.         local_program_counter;
  1139.  
  1140.     VariableSymbol *accessed_local;
  1141.     MethodSymbol *read_method,
  1142.                  *write_method;
  1143.  
  1144.     virtual wchar_t *Name() { return name_symbol -> Name(); }
  1145.     virtual int NameLength() { return name_symbol -> NameLength(); }
  1146.     virtual NameSymbol *Identity() { return name_symbol; }
  1147.     char *Utf8Name() { return (char *) (name_symbol -> Utf8_literal ? name_symbol -> Utf8_literal -> value : NULL); }
  1148.     int Utf8NameLength() { return (name_symbol -> Utf8_literal ? name_symbol -> Utf8_literal -> length : 0); }
  1149.  
  1150.     void SetExternalIdentity(NameSymbol *external_name_symbol_) { external_name_symbol = external_name_symbol_; }
  1151.     NameSymbol *ExternalIdentity()
  1152.     {
  1153.         return (external_name_symbol ? external_name_symbol : name_symbol);
  1154.     }
  1155.     wchar_t *ExternalName()
  1156.     {
  1157.         return (external_name_symbol ? external_name_symbol -> Name() : name_symbol -> Name());
  1158.     }
  1159.     int ExternalNameLength()
  1160.     {
  1161.         return (external_name_symbol ? external_name_symbol -> NameLength() : name_symbol -> NameLength());
  1162.     }
  1163.     char *ExternalUtf8Name()
  1164.     {
  1165.         return (char *) (external_name_symbol ? external_name_symbol -> Utf8_literal -> value
  1166.                                               : (name_symbol -> Utf8_literal ? name_symbol -> Utf8_literal -> value : NULL));
  1167.     }
  1168.     int ExternalUtf8NameLength()
  1169.     {
  1170.         return (external_name_symbol ? (external_name_symbol -> Utf8_literal ? external_name_symbol -> Utf8_literal -> length : 0)
  1171.                                      : (name_symbol -> Utf8_literal ? name_symbol -> Utf8_literal -> length : 0));
  1172.     }
  1173.  
  1174.     VariableSymbol(NameSymbol *name_symbol_) : declarator(NULL),
  1175.                                                name_symbol(name_symbol_),
  1176.                                                external_name_symbol(NULL),
  1177.                                                owner(NULL),
  1178.                                                type_(NULL),
  1179.                                                signature_string(NULL),
  1180.                                                initial_value(NULL),
  1181.                                                local_variable_index_(-1), 
  1182.                                                constant_pool_index(0),
  1183.                                                constant_pool_class(0),
  1184.                                                local_program_counter(0),
  1185.                                                accessed_local(NULL),
  1186.                                                read_method(NULL),
  1187.                                                write_method(NULL),
  1188.                                                status(0)
  1189.     {
  1190.         Symbol::_kind = VARIABLE;
  1191.     }
  1192.  
  1193.     virtual ~VariableSymbol() { delete [] signature_string; }
  1194.  
  1195.     void SetFlags(AccessFlags variable_access) { access_flags = variable_access.access_flags; }
  1196.     void SetOwner(Symbol *owner_) { owner = owner_; }
  1197.  
  1198.     void SetLocalVariableIndex(int index)
  1199.     {
  1200.         local_variable_index_ = index;
  1201.         MarkComplete();
  1202.     }
  1203.     int LocalVariableIndex() { return local_variable_index_; }
  1204.  
  1205.     bool IsTyped()
  1206.     {
  1207.         return type_ != NULL;
  1208.     }
  1209.  
  1210.     void SetType(TypeSymbol *_type)
  1211.     {
  1212.         type_ = _type;
  1213.     }
  1214.  
  1215.     void ProcessVariableSignature(Semantic *, LexStream::TokenIndex);
  1216.  
  1217.     TypeSymbol *Type(Semantic *sem = NULL, LexStream::TokenIndex tok = 0)
  1218.     {
  1219.         if (! type_)
  1220.             ProcessVariableSignature(sem, tok);
  1221. assert(type_);
  1222.         return type_;
  1223.     }
  1224.  
  1225.     void SetSignatureString(char *signature_, int length)
  1226.     {
  1227.         signature_string = new char[length + 1];
  1228.         strncpy(signature_string, signature_, length);
  1229.         signature_string[length] = U_NULL;
  1230.     }
  1231.  
  1232.     bool IsLocal()                     { return owner -> MethodCast() != NULL; }           // is variable a local variable?
  1233.     bool IsLocal(MethodSymbol *method) { return owner == method; } // is variable local to a particular method ?
  1234.     bool IsFinal(TypeSymbol *type)     { return (owner == type && ACC_FINAL()); }
  1235.  
  1236.     //
  1237.     // These functions are used to identify when the declaration of a field in the body of a class is
  1238.     // complete.
  1239.     //
  1240.     void MarkIncomplete()         { status &= (~((unsigned char) 0x01)); }
  1241.     void MarkComplete()           { status |= (unsigned char) 0x01; }
  1242.     bool IsDeclarationComplete()  { return status & (unsigned char) 0x01; }
  1243.  
  1244.     void MarkNotDefinitelyAssigned() { status &= (~((unsigned char) 0x02)); }
  1245.     void MarkDefinitelyAssigned()    { status |= (unsigned char) 0x02; }
  1246.     bool IsDefinitelyAssigned()      { return status & (unsigned char) 0x02; }
  1247.  
  1248.     void MarkPossiblyAssigned() { status |= (unsigned char) 0x04; }
  1249.     bool IsPossiblyAssigned()   { return status & (unsigned char) 0x04; }
  1250.  
  1251.     void MarkSynthetic() { status |= (unsigned char) 0x08; }
  1252.     bool IsSynthetic()   { return status & (unsigned char) 0x08; }
  1253.  
  1254. private:
  1255.     NameSymbol *external_name_symbol;
  1256.  
  1257.     unsigned char status;
  1258.     int local_variable_index_;
  1259.     TypeSymbol *type_;
  1260.     char *signature_string;
  1261. };
  1262.  
  1263.  
  1264. class BlockSymbol : public Symbol
  1265. public:
  1266.     int max_variable_index,
  1267.         synchronized_variable_index,
  1268.         try_variable_index;
  1269.  
  1270.     BlockSymbol(int hash_size);
  1271.     virtual ~BlockSymbol();
  1272.  
  1273.     int NumVariableSymbols();
  1274.     VariableSymbol *VariableSym(int);
  1275.  
  1276.     inline VariableSymbol *FindVariableSymbol(NameSymbol *);
  1277.     inline VariableSymbol *InsertVariableSymbol(NameSymbol *);
  1278.     inline void InsertVariableSymbol(VariableSymbol *);
  1279.     inline BlockSymbol *InsertBlockSymbol(int);
  1280.  
  1281.     inline void CompressSpace();
  1282.  
  1283.     inline SymbolTable *Table();
  1284.  
  1285. private:
  1286.  
  1287.     SymbolTable *table;
  1288. };
  1289.  
  1290.  
  1291. class LabelSymbol : public Symbol
  1292. public:
  1293.     AstBlock *block; // the block that is labeled by this symbol
  1294.     NameSymbol *name_symbol;
  1295.  
  1296.     int nesting_level;
  1297.  
  1298.     virtual wchar_t *Name() { return name_symbol -> Name(); }
  1299.     virtual int NameLength() { return name_symbol -> NameLength(); }
  1300.     virtual NameSymbol *Identity() { return name_symbol; }
  1301.     char *Utf8Name() { return (char *) (name_symbol -> Utf8_literal ? name_symbol -> Utf8_literal -> value : NULL); }
  1302.     int Utf8NameLength() { return (name_symbol -> Utf8_literal ? name_symbol -> Utf8_literal -> length : 0); }
  1303.  
  1304.     LabelSymbol(NameSymbol *name_symbol_) : block(NULL),
  1305.                                             nesting_level(0),
  1306.                                             name_symbol(name_symbol_)
  1307.     {
  1308.         Symbol::_kind = LABEL;
  1309.     }
  1310.  
  1311.     virtual ~LabelSymbol() {}
  1312.  
  1313. private:
  1314. };
  1315.  
  1316.  
  1317. class SymbolTable
  1318. {
  1319. public:
  1320.     enum
  1321.     {
  1322.         DEFAULT_HASH_SIZE = 13,
  1323.         MAX_HASH_SIZE = 1021
  1324.     };
  1325.  
  1326.     int NumAnonymousSymbols()
  1327.     {
  1328.         return (anonymous_symbol_pool ? anonymous_symbol_pool -> Length() : 0);
  1329.     }
  1330.     TypeSymbol *AnonymousSym(int i)
  1331.     {
  1332.         return (*anonymous_symbol_pool)[i];
  1333.     }
  1334.     void AddAnonymousSymbol(TypeSymbol *symbol)
  1335.     {
  1336.         if (! anonymous_symbol_pool)
  1337.             anonymous_symbol_pool = new ConvertibleArray<TypeSymbol *>(256);
  1338.         anonymous_symbol_pool -> Next() = symbol;
  1339.     }
  1340.  
  1341.     int NumTypeSymbols()
  1342.     {
  1343.         return (type_symbol_pool ? type_symbol_pool -> Length() : 0);
  1344.     }
  1345.     TypeSymbol *&TypeSym(int i)
  1346.     {
  1347.         return (*type_symbol_pool)[i];
  1348.     }
  1349.     void AddTypeSymbol(TypeSymbol *symbol)
  1350.     {
  1351.         if (! type_symbol_pool)
  1352.             type_symbol_pool = new ConvertibleArray<TypeSymbol *>(256);
  1353.         type_symbol_pool -> Next() = symbol;
  1354.     }
  1355.  
  1356.     int NumMethodSymbols()
  1357.     {
  1358.         return (method_symbol_pool ? method_symbol_pool -> Length() : 0);
  1359.     }
  1360.     MethodSymbol *MethodSym(int i)
  1361.     {
  1362.         return (*method_symbol_pool)[i];
  1363.     }
  1364.     void AddMethodSymbol(MethodSymbol *symbol)
  1365.     {
  1366.         if (! method_symbol_pool)
  1367.             method_symbol_pool = new ConvertibleArray<MethodSymbol *>(256);
  1368.         method_symbol_pool -> Next() = symbol;
  1369.     }
  1370.  
  1371.     int NumVariableSymbols()
  1372.     {
  1373.         return (variable_symbol_pool ? variable_symbol_pool -> Length() : 0);
  1374.     }
  1375.     VariableSymbol *VariableSym(int i)
  1376.     {
  1377.         return (*variable_symbol_pool)[i];
  1378.     }
  1379.     void AddVariableSymbol(VariableSymbol *symbol)
  1380.     {
  1381.         if (! variable_symbol_pool)
  1382.             variable_symbol_pool = new ConvertibleArray<VariableSymbol *>(256);
  1383.         variable_symbol_pool -> Next() = symbol;
  1384.     }
  1385.  
  1386.     int NumOtherSymbols()
  1387.     {
  1388.         return (other_symbol_pool ? other_symbol_pool -> Length() : 0);
  1389.     }
  1390.     Symbol *OtherSym(int i)
  1391.     {
  1392.         return (*other_symbol_pool)[i];
  1393.     }
  1394.     void AddOtherSymbol(Symbol *symbol)
  1395.     {
  1396.         if (! other_symbol_pool)
  1397.             other_symbol_pool = new ConvertibleArray<Symbol *>(256);
  1398.         other_symbol_pool -> Next() = symbol;
  1399.     }
  1400.  
  1401.     SymbolTable(int hash_size_ = DEFAULT_HASH_SIZE);
  1402.     ~SymbolTable();
  1403.  
  1404.     inline void CompressSpace()
  1405.     {
  1406.         if (anonymous_symbol_pool)
  1407.             (void) anonymous_symbol_pool -> Array();
  1408.         if (method_symbol_pool)
  1409.             (void) method_symbol_pool -> Array();
  1410.         if (variable_symbol_pool)
  1411.             (void) variable_symbol_pool -> Array();
  1412.         if (other_symbol_pool)
  1413.             (void) other_symbol_pool -> Array();
  1414.  
  1415.         return;
  1416.     }
  1417.  
  1418. private:
  1419.  
  1420.     Tuple<TypeSymbol *> *type_symbol_pool; // This array should not be convertible. See SymbolTable::DeleteTypeSymbol
  1421.  
  1422.     ConvertibleArray<TypeSymbol *>     *anonymous_symbol_pool;
  1423.     ConvertibleArray<MethodSymbol *>   *method_symbol_pool;
  1424.     ConvertibleArray<VariableSymbol *> *variable_symbol_pool;
  1425.     ConvertibleArray<Symbol *>         *other_symbol_pool;
  1426.  
  1427.     Symbol **base;
  1428.     int hash_size;
  1429.  
  1430.     static int primes[];
  1431.     int prime_index;
  1432.  
  1433.     int Size()
  1434.     {
  1435.         return NumAnonymousSymbols() +
  1436.                NumTypeSymbols() +
  1437.                NumMethodSymbols() +
  1438.                NumVariableSymbols() +
  1439.                NumOtherSymbols();
  1440.     }
  1441.     void Rehash();
  1442.  
  1443.     MethodSymbol *constructor;
  1444.  
  1445. public:
  1446.  
  1447.     inline PathSymbol *InsertPathSymbol(NameSymbol *, DirectorySymbol *);
  1448.     inline PathSymbol *FindPathSymbol(NameSymbol *);
  1449.     inline DirectorySymbol *InsertDirectorySymbol(NameSymbol *, Symbol *);
  1450.     inline DirectorySymbol *InsertAndReadDirectorySymbol(NameSymbol *, Symbol *);
  1451.     inline DirectorySymbol *FindDirectorySymbol(NameSymbol *);
  1452.     inline FileSymbol *InsertFileSymbol(NameSymbol *);
  1453.     inline FileSymbol *FindFileSymbol(NameSymbol *);
  1454.     inline PackageSymbol *InsertPackageSymbol(NameSymbol *, PackageSymbol *);
  1455.     inline PackageSymbol *FindPackageSymbol(NameSymbol *);
  1456.     inline TypeSymbol *InsertAnonymousTypeSymbol(NameSymbol *);
  1457.     inline TypeSymbol *InsertSystemTypeSymbol(NameSymbol *);
  1458.     inline TypeSymbol *InsertOuterTypeSymbol(NameSymbol *);
  1459.     inline TypeSymbol *InsertNestedTypeSymbol(NameSymbol *);
  1460.     inline void DeleteTypeSymbol(TypeSymbol *);
  1461.     inline void DeleteAnonymousTypes();
  1462.     inline TypeSymbol *FindTypeSymbol(NameSymbol *);
  1463.     inline MethodSymbol *InsertMethodSymbol(NameSymbol *);
  1464.     inline MethodSymbol *InsertConstructorSymbol(NameSymbol *);
  1465.     inline void InsertMethodSymbol(MethodSymbol *);
  1466.     inline void InsertConstructorSymbol(MethodSymbol *);
  1467.     inline MethodSymbol *FindMethodSymbol(NameSymbol *);
  1468.     inline MethodSymbol *FindConstructorSymbol();
  1469.     inline VariableSymbol *InsertVariableSymbol(NameSymbol *);
  1470.     inline void InsertVariableSymbol(VariableSymbol *);
  1471.     inline VariableSymbol *FindVariableSymbol(NameSymbol *);
  1472.     inline LabelSymbol *InsertLabelSymbol(NameSymbol *);
  1473.     inline LabelSymbol *FindLabelSymbol(NameSymbol *);
  1474.     inline BlockSymbol *InsertBlockSymbol(int);
  1475.  
  1476.     inline MethodSymbol *Overload(MethodSymbol *);
  1477.     inline void Overload(MethodSymbol *, MethodSymbol *);
  1478.     inline MethodSymbol *LocalConstructorOverload(MethodSymbol *);
  1479.     MethodSymbol *FindOverloadMethod(MethodSymbol *, AstMethodDeclarator *);
  1480. };
  1481.  
  1482.  
  1483. inline int TypeSymbol::NumVariableSymbols() { return (table ? table -> NumVariableSymbols() : 0); }
  1484. inline int BlockSymbol::NumVariableSymbols() { return (table ? table -> NumVariableSymbols() : 0); }
  1485.  
  1486. inline VariableSymbol *TypeSymbol::VariableSym(int i) { return table -> VariableSym(i); }
  1487. inline VariableSymbol *BlockSymbol::VariableSym(int i) { return table -> VariableSym(i); }
  1488.  
  1489. inline int TypeSymbol::NumMethodSymbols() { return (table ? table -> NumMethodSymbols() : 0); }
  1490.  
  1491. inline MethodSymbol *TypeSymbol::MethodSym(int i) { return table -> MethodSym(i); }
  1492.  
  1493. inline int TypeSymbol::NumTypeSymbols() { return (table ? table -> NumTypeSymbols() : 0); }
  1494.  
  1495. inline TypeSymbol *TypeSymbol::TypeSym(int i) { return table -> TypeSym(i); }
  1496.  
  1497. inline void TypeSymbol::CompressSpace() { if (table) table -> CompressSpace(); }
  1498. inline void BlockSymbol::CompressSpace() { if (table) table -> CompressSpace(); }
  1499.  
  1500. inline PathSymbol *SymbolTable::InsertPathSymbol(NameSymbol *name_symbol, DirectorySymbol *directory_symbol)
  1501. {
  1502. assert(base);
  1503.     PathSymbol *symbol = new PathSymbol(name_symbol);
  1504.     directory_symbol -> owner = symbol;
  1505.     symbol -> root_directory = directory_symbol;
  1506.     AddOtherSymbol(symbol);
  1507.  
  1508.     int k = name_symbol -> index % hash_size;
  1509.     symbol -> next = base[k];
  1510.     base[k] = symbol;
  1511.  
  1512.     //
  1513.     // If the set is "adjustable" and the number of unique elements in it exceeds
  1514.     // 2 times the size of the base, and we have not yet reached the maximum
  1515.     // allowable size for a base, reallocate a larger base and rehash the elements.
  1516.     //
  1517.     if ((hash_size < MAX_HASH_SIZE) && (Size() > (hash_size << 1)))
  1518.         Rehash();
  1519.  
  1520.     return symbol;
  1521. }
  1522.  
  1523.  
  1524. inline PathSymbol *SymbolTable::FindPathSymbol(NameSymbol *name_symbol)
  1525. {
  1526. assert(base);
  1527.     for (Symbol *symbol = base[name_symbol -> index % hash_size]; symbol; symbol = symbol -> next)
  1528.     {
  1529.         if (name_symbol == symbol -> Identity())
  1530.             return (PathSymbol *) symbol;
  1531.     }
  1532.  
  1533.     return (PathSymbol *) NULL;
  1534. }
  1535.  
  1536.  
  1537. inline DirectorySymbol *SymbolTable::InsertDirectorySymbol(NameSymbol *name_symbol, Symbol *owner)
  1538. {
  1539. assert(base);
  1540.     DirectorySymbol *symbol = new DirectorySymbol(name_symbol, owner);
  1541.     AddOtherSymbol(symbol);
  1542.  
  1543.     int k = name_symbol -> index % hash_size;
  1544.     symbol -> next = base[k];
  1545.     base[k] = symbol;
  1546.  
  1547.     //
  1548.     // If the set is "adjustable" and the number of unique elements in it exceeds
  1549.     // 2 times the size of the base, and we have not yet reached the maximum
  1550.     // allowable size for a base, reallocate a larger base and rehash the elements.
  1551.     //
  1552.     if ((hash_size < MAX_HASH_SIZE) && (Size() > (hash_size << 1)))
  1553.         Rehash();
  1554.  
  1555.     return symbol;
  1556. }
  1557.  
  1558.  
  1559. inline DirectorySymbol *SymbolTable::InsertAndReadDirectorySymbol(NameSymbol *name_symbol, Symbol *owner)
  1560. {
  1561.     DirectorySymbol *subdirectory_symbol = InsertDirectorySymbol(name_symbol, owner);
  1562.     subdirectory_symbol -> ResetDirectory();
  1563.  
  1564.     return subdirectory_symbol;
  1565. }
  1566.  
  1567.  
  1568. inline DirectorySymbol *DirectorySymbol::InsertDirectorySymbol(NameSymbol *name_symbol)
  1569. {
  1570.     DirectorySymbol *subdirectory_symbol = Table() -> InsertDirectorySymbol(name_symbol, this);
  1571.     this -> subdirectories.Next() = subdirectory_symbol;
  1572.  
  1573.     return subdirectory_symbol;
  1574. }
  1575.  
  1576.  
  1577. inline DirectorySymbol *DirectorySymbol::InsertAndReadDirectorySymbol(NameSymbol *name_symbol)
  1578. {
  1579.     DirectorySymbol *subdirectory_symbol = Table() -> InsertAndReadDirectorySymbol(name_symbol, this);
  1580.     this -> subdirectories.Next() = subdirectory_symbol;
  1581.  
  1582.     return subdirectory_symbol;
  1583. }
  1584.  
  1585.  
  1586. inline DirectorySymbol *SymbolTable::FindDirectorySymbol(NameSymbol *name_symbol)
  1587. {
  1588. assert(base);
  1589.     for (Symbol *symbol = base[name_symbol -> index % hash_size]; symbol; symbol = symbol -> next)
  1590.     {
  1591.         if (name_symbol == symbol -> Identity())
  1592.         {
  1593.             DirectorySymbol *directory_symbol = symbol -> DirectoryCast();
  1594.             if (directory_symbol)
  1595.                 return directory_symbol;
  1596.         }
  1597.     }
  1598.  
  1599.     return (DirectorySymbol *) NULL;
  1600. }
  1601.  
  1602.  
  1603. inline DirectorySymbol *DirectorySymbol::FindDirectorySymbol(NameSymbol *name_symbol)
  1604. {
  1605.     return (table ? table -> FindDirectorySymbol(name_symbol) : (DirectorySymbol *) NULL);
  1606. }
  1607.  
  1608.  
  1609. inline FileSymbol *SymbolTable::InsertFileSymbol(NameSymbol *name_symbol)
  1610. {
  1611. assert(base);
  1612.     FileSymbol *symbol = new FileSymbol(name_symbol);
  1613.     AddOtherSymbol(symbol);
  1614.  
  1615.     int k = name_symbol -> index % hash_size;
  1616.     symbol -> next = base[k];
  1617.     base[k] = symbol;
  1618.  
  1619.     //
  1620.     // If the set is "adjustable" and the number of unique elements in it exceeds
  1621.     // 2 times the size of the base, and we have not yet reached the maximum
  1622.     // allowable size for a base, reallocate a larger base and rehash the elements.
  1623.     //
  1624.     if ((hash_size < MAX_HASH_SIZE) && (Size() > (hash_size << 1)))
  1625.         Rehash();
  1626.  
  1627.     return symbol;
  1628. }
  1629.  
  1630.  
  1631. inline FileSymbol *DirectorySymbol::InsertFileSymbol(NameSymbol *name_symbol)
  1632. {
  1633.     return Table() -> InsertFileSymbol(name_symbol);
  1634. }
  1635.  
  1636.  
  1637. inline FileSymbol *SymbolTable::FindFileSymbol(NameSymbol *name_symbol)
  1638. {
  1639. assert(base);
  1640.     for (Symbol *symbol = base[name_symbol -> index % hash_size]; symbol; symbol = symbol -> next)
  1641.     {
  1642.         if (name_symbol == symbol -> Identity())
  1643.         {
  1644.             FileSymbol *file_symbol = symbol -> FileCast();
  1645.             if (file_symbol)
  1646.                 return file_symbol;
  1647.         }
  1648.     }
  1649.  
  1650.     return (FileSymbol *) NULL;
  1651. }
  1652.  
  1653.  
  1654. inline FileSymbol *DirectorySymbol::FindFileSymbol(NameSymbol *name_symbol)
  1655. {
  1656.     return (table ? table -> FindFileSymbol(name_symbol) : (FileSymbol *) NULL);
  1657. }
  1658.  
  1659.  
  1660. inline PackageSymbol *SymbolTable::InsertPackageSymbol(NameSymbol *name_symbol, PackageSymbol *owner)
  1661. {
  1662. assert(base);
  1663.     PackageSymbol *symbol = new PackageSymbol(name_symbol, owner);
  1664.     AddOtherSymbol(symbol);
  1665.  
  1666.     int k = name_symbol -> index % hash_size;
  1667.     symbol -> next = base[k];
  1668.     base[k] = symbol;
  1669.  
  1670.     //
  1671.     // If the set is "adjustable" and the number of unique elements in it exceeds
  1672.     // 2 times the size of the base, and we have not yet reached the maximum
  1673.     // allowable size for a base, reallocate a larger base and rehash the elements.
  1674.     //
  1675.     if ((hash_size < MAX_HASH_SIZE) && (Size() > (hash_size << 1)))
  1676.         Rehash();
  1677.  
  1678.     return symbol;
  1679. }
  1680.  
  1681.  
  1682. inline PackageSymbol *PackageSymbol::InsertPackageSymbol(NameSymbol *name_symbol)
  1683. {
  1684.     return Table() -> InsertPackageSymbol(name_symbol, this);
  1685. }
  1686.  
  1687.  
  1688. inline PackageSymbol *SymbolTable::FindPackageSymbol(NameSymbol *name_symbol)
  1689. {
  1690. assert(base);
  1691.     for (Symbol *symbol = base[name_symbol -> index % hash_size]; symbol; symbol = symbol -> next)
  1692.     {
  1693.         if (name_symbol == symbol -> Identity())
  1694.         {
  1695.             PackageSymbol *package_symbol = symbol -> PackageCast();
  1696.             if (package_symbol)
  1697.                 return package_symbol;
  1698.         }
  1699.     }
  1700.  
  1701.     return (PackageSymbol *) NULL;
  1702. }
  1703.  
  1704.  
  1705. inline PackageSymbol *PackageSymbol::FindPackageSymbol(NameSymbol *name_symbol)
  1706. {
  1707.   return (table ? table -> FindPackageSymbol(name_symbol) : (PackageSymbol *) NULL);
  1708. }
  1709.  
  1710. inline TypeSymbol *SymbolTable::InsertAnonymousTypeSymbol(NameSymbol *name_symbol)
  1711. {
  1712.     TypeSymbol *symbol = new TypeSymbol(name_symbol);
  1713.     AddAnonymousSymbol(symbol);
  1714.  
  1715.     return symbol;
  1716. }
  1717.  
  1718.  
  1719. inline TypeSymbol *TypeSymbol::InsertAnonymousTypeSymbol(NameSymbol *name_symbol)
  1720. {
  1721.     return Table() -> InsertAnonymousTypeSymbol(name_symbol);
  1722. }
  1723.  
  1724.  
  1725. inline TypeSymbol *SymbolTable::InsertSystemTypeSymbol(NameSymbol *name_symbol)
  1726. {
  1727. assert(base);
  1728.     TypeSymbol *symbol = new TypeSymbol(name_symbol);
  1729.     symbol -> pool_index = NumTypeSymbols();
  1730.     AddTypeSymbol(symbol);
  1731.  
  1732.     int k = name_symbol -> index % hash_size;
  1733.     symbol -> next = base[k];
  1734.     base[k] = symbol;
  1735.  
  1736.     //
  1737.     // If the set is "adjustable" and the number of unique elements in it exceeds
  1738.     // 2 times the size of the base, and we have not yet reached the maximum
  1739.     // allowable size for a base, reallocate a larger base and rehash the elements.
  1740.     //
  1741.     if ((hash_size < MAX_HASH_SIZE) && (Size() > (hash_size << 1)))
  1742.         Rehash();
  1743.  
  1744.     return symbol;
  1745. }
  1746.  
  1747.  
  1748. inline TypeSymbol *PackageSymbol::InsertSystemTypeSymbol(NameSymbol *name_symbol)
  1749. {
  1750.     return Table() -> InsertSystemTypeSymbol(name_symbol);
  1751. }
  1752.  
  1753.  
  1754. inline TypeSymbol *SymbolTable::InsertOuterTypeSymbol(NameSymbol *name_symbol)
  1755. {
  1756. assert(base);
  1757.     TypeSymbol *symbol = new TypeSymbol(name_symbol);
  1758.     symbol -> pool_index = NumTypeSymbols();
  1759.     AddTypeSymbol(symbol);
  1760.  
  1761.     int k = name_symbol -> index % hash_size;
  1762.     symbol -> next = base[k];
  1763.     base[k] = symbol;
  1764.  
  1765.     //
  1766.     // If the set is "adjustable" and the number of unique elements in it exceeds
  1767.     // 2 times the size of the base, and we have not yet reached the maximum
  1768.     // allowable size for a base, reallocate a larger base and rehash the elements.
  1769.     //
  1770.     if ((hash_size < MAX_HASH_SIZE) && (Size() > (hash_size << 1)))
  1771.         Rehash();
  1772.  
  1773.     return symbol;
  1774. }
  1775.  
  1776.  
  1777. inline TypeSymbol *PackageSymbol::InsertOuterTypeSymbol(NameSymbol *name_symbol)
  1778. {
  1779.     return Table() -> InsertOuterTypeSymbol(name_symbol);
  1780. }
  1781.  
  1782.  
  1783. inline TypeSymbol *SymbolTable::InsertNestedTypeSymbol(NameSymbol *name_symbol)
  1784. {
  1785. assert(base);
  1786.     TypeSymbol *symbol = new TypeSymbol(name_symbol);
  1787.     symbol -> pool_index = NumTypeSymbols();
  1788.     AddTypeSymbol(symbol);
  1789.  
  1790.     int k = name_symbol -> index % hash_size;
  1791.     symbol -> next = base[k];
  1792.     base[k] = symbol;
  1793.  
  1794.     //
  1795.     // If the set is "adjustable" and the number of unique elements in it exceeds
  1796.     // 2 times the size of the base, and we have not yet reached the maximum
  1797.     // allowable size for a base, reallocate a larger base and rehash the elements.
  1798.     //
  1799.     if ((hash_size < MAX_HASH_SIZE) && (Size() > (hash_size << 1)))
  1800.         Rehash();
  1801.  
  1802.     return symbol;
  1803. }
  1804.  
  1805.  
  1806. inline TypeSymbol *TypeSymbol::InsertNestedTypeSymbol(NameSymbol *name_symbol)
  1807. {
  1808.     return Table() -> InsertNestedTypeSymbol(name_symbol);
  1809. }
  1810.  
  1811.  
  1812. inline void SymbolTable::DeleteTypeSymbol(TypeSymbol *type)
  1813. {
  1814. assert(base);
  1815.     int k = type -> name_symbol -> index % hash_size;
  1816.     if (type == base[k])
  1817.         base[k] = type -> next;
  1818.     else
  1819.     {
  1820.         Symbol *previous = base[k];
  1821.         for (Symbol *symbol = previous -> next; symbol != type; previous = symbol, symbol = symbol -> next)
  1822.             ;
  1823.         previous -> next = type -> next;
  1824.     }
  1825.  
  1826.     int last_index = NumTypeSymbols() - 1;
  1827.     if (type -> pool_index != last_index)
  1828.     {// move last element to position previously occupied by element being deleted
  1829.         TypeSym(last_index) -> pool_index = type -> pool_index;
  1830.         TypeSym(type -> pool_index) = TypeSym(last_index);
  1831.     }
  1832.  
  1833.     type_symbol_pool -> Reset(last_index); // remove last slot in symbol_pool
  1834.  
  1835.     delete type;
  1836.  
  1837.     return;
  1838. }
  1839.  
  1840.  
  1841. inline void PackageSymbol::DeleteTypeSymbol(TypeSymbol *type)
  1842. {
  1843.     if (table)
  1844.         table -> DeleteTypeSymbol(type);
  1845. }
  1846.  
  1847.  
  1848. inline void SymbolTable::DeleteAnonymousTypes()
  1849. {
  1850.     for (int i = 0; i < NumAnonymousSymbols(); i++)
  1851.         delete AnonymousSym(i);
  1852.     delete anonymous_symbol_pool;
  1853.     anonymous_symbol_pool = NULL;
  1854.  
  1855.     return;
  1856. }
  1857.  
  1858.  
  1859. inline void TypeSymbol::DeleteAnonymousTypes()
  1860. {
  1861.     delete anonymous_types;
  1862.     anonymous_types = NULL;
  1863.     if (table)
  1864.         table -> DeleteAnonymousTypes();
  1865. }
  1866.  
  1867. inline TypeSymbol *SymbolTable::FindTypeSymbol(NameSymbol *name_symbol)
  1868. {
  1869. assert(base);
  1870.     for (Symbol *symbol = base[name_symbol -> index % hash_size]; symbol; symbol = symbol -> next)
  1871.     {
  1872.         if (name_symbol == symbol -> Identity())
  1873.         {
  1874.             TypeSymbol *type = symbol -> TypeCast();
  1875.             if (type)
  1876.                 return type;
  1877.         }
  1878.     }
  1879.  
  1880.     return (TypeSymbol *) NULL;
  1881. }
  1882.  
  1883.  
  1884. inline TypeSymbol *PackageSymbol::FindTypeSymbol(NameSymbol *name_symbol)
  1885. {
  1886.     return (table ? table -> FindTypeSymbol(name_symbol) : (TypeSymbol *) NULL);
  1887. }
  1888.  
  1889.  
  1890. inline TypeSymbol *TypeSymbol::FindTypeSymbol(NameSymbol *name_symbol)
  1891. {
  1892.     return (table ? table -> FindTypeSymbol(name_symbol) : (TypeSymbol *) NULL);
  1893. }
  1894.  
  1895.  
  1896. inline MethodSymbol *SymbolTable::InsertMethodSymbol(NameSymbol *name_symbol)
  1897. {
  1898. assert(base);
  1899.     MethodSymbol *symbol = new MethodSymbol(name_symbol);
  1900.     AddMethodSymbol(symbol);
  1901.  
  1902.     int k = name_symbol -> index % hash_size;
  1903.     symbol -> next = base[k];
  1904.     base[k] = symbol;
  1905.  
  1906.     //
  1907.     // If the set is "adjustable" and the number of unique elements in it exceeds
  1908.     // 2 times the size of the base, and we have not yet reached the maximum
  1909.     // allowable size for a base, reallocate a larger base and rehash the elements.
  1910.     //
  1911.     if ((hash_size < MAX_HASH_SIZE) && (Size() > (hash_size << 1)))
  1912.         Rehash();
  1913.  
  1914.     return symbol;
  1915. }
  1916.  
  1917.  
  1918. inline MethodSymbol *TypeSymbol::InsertMethodSymbol(NameSymbol *name_symbol)
  1919. {
  1920.     return Table() -> InsertMethodSymbol(name_symbol);
  1921. }
  1922.  
  1923.  
  1924. inline MethodSymbol *SymbolTable::InsertConstructorSymbol(NameSymbol *name_symbol)
  1925. {
  1926. assert(! constructor);
  1927.     this -> constructor = InsertMethodSymbol(name_symbol);
  1928.     return this -> constructor;
  1929. }
  1930.  
  1931.  
  1932. inline MethodSymbol *TypeSymbol::InsertConstructorSymbol(NameSymbol *name_symbol)
  1933. {
  1934.     return Table() -> InsertConstructorSymbol(name_symbol);
  1935. }
  1936.  
  1937.  
  1938. inline void SymbolTable::InsertMethodSymbol(MethodSymbol *method_symbol)
  1939. {
  1940. assert(base);
  1941.     AddMethodSymbol(method_symbol);
  1942.  
  1943.     int k = method_symbol -> name_symbol -> index % hash_size;
  1944.     method_symbol -> next = base[k];
  1945.     base[k] = method_symbol;
  1946.  
  1947.     //
  1948.     // If the set is "adjustable" and the number of unique elements in it exceeds
  1949.     // 2 times the size of the base, and we have not yet reached the maximum
  1950.     // allowable size for a base, reallocate a larger base and rehash the elements.
  1951.     //
  1952.     if ((hash_size < MAX_HASH_SIZE) && (Size() > (hash_size << 1)))
  1953.         Rehash();
  1954.  
  1955.     return;
  1956. }
  1957.  
  1958.  
  1959. inline void TypeSymbol::InsertMethodSymbol(MethodSymbol *method_symbol)
  1960. {
  1961.     Table() -> InsertMethodSymbol(method_symbol);
  1962. }
  1963.  
  1964.  
  1965. inline void SymbolTable::InsertConstructorSymbol(MethodSymbol *method_symbol)
  1966. {
  1967. assert(! constructor);
  1968.     this -> constructor = method_symbol;
  1969.     InsertMethodSymbol(method_symbol);
  1970. }
  1971.  
  1972.  
  1973. inline void TypeSymbol::InsertConstructorSymbol(MethodSymbol *method_symbol)
  1974. {
  1975.     Table() -> InsertConstructorSymbol(method_symbol);
  1976. }
  1977.  
  1978.  
  1979. inline MethodSymbol *SymbolTable::FindMethodSymbol(NameSymbol *name_symbol)
  1980. {
  1981. assert(base);
  1982.     for (Symbol *symbol = base[name_symbol -> index % hash_size]; symbol; symbol = symbol -> next)
  1983.     {
  1984.         if (name_symbol == symbol -> Identity())
  1985.         {
  1986.             MethodSymbol *method = symbol -> MethodCast();
  1987.             if (method)
  1988.                 return method;
  1989.         }
  1990.     }
  1991.  
  1992.     return (MethodSymbol *) NULL;
  1993. }
  1994.  
  1995.  
  1996. inline MethodSymbol *TypeSymbol::FindMethodSymbol(NameSymbol *name_symbol)
  1997. {
  1998.     return (table ? table -> FindMethodSymbol(name_symbol) : (MethodSymbol *) NULL);
  1999. }
  2000.  
  2001.  
  2002. inline MethodSymbol *SymbolTable::FindConstructorSymbol()
  2003. {
  2004.     return this -> constructor;
  2005. }
  2006.  
  2007. inline MethodSymbol *TypeSymbol::FindConstructorSymbol()
  2008. {
  2009.     return (table ? table -> FindConstructorSymbol() : (MethodSymbol *) NULL);
  2010. }
  2011.  
  2012. inline VariableSymbol *SymbolTable::InsertVariableSymbol(NameSymbol *name_symbol)
  2013. {
  2014. assert(base);
  2015.     VariableSymbol *symbol = new VariableSymbol(name_symbol);
  2016.     AddVariableSymbol(symbol);
  2017.  
  2018.     int k = name_symbol -> index % hash_size;
  2019.     symbol -> next = base[k];
  2020.     base[k] = symbol;
  2021.  
  2022.     //
  2023.     // If the set is "adjustable" and the number of unique elements in it exceeds
  2024.     // 2 times the size of the base, and we have not yet reached the maximum
  2025.     // allowable size for a base, reallocate a larger base and rehash the elements.
  2026.     //
  2027.     if ((hash_size < MAX_HASH_SIZE) && (Size() > (hash_size << 1)))
  2028.         Rehash();
  2029.  
  2030.     return symbol;
  2031. }
  2032.  
  2033.  
  2034. inline VariableSymbol *TypeSymbol::InsertVariableSymbol(NameSymbol *name_symbol)
  2035. {
  2036.     return Table() -> InsertVariableSymbol(name_symbol);
  2037. }
  2038.  
  2039.  
  2040. inline VariableSymbol *BlockSymbol::InsertVariableSymbol(NameSymbol *name_symbol)
  2041. {
  2042.     return Table() -> InsertVariableSymbol(name_symbol);
  2043. }
  2044.  
  2045.  
  2046. inline void SymbolTable::InsertVariableSymbol(VariableSymbol *variable_symbol)
  2047. {
  2048. assert(base);
  2049.     AddVariableSymbol(variable_symbol);
  2050.  
  2051.     int k = variable_symbol -> name_symbol -> index % hash_size;
  2052.     variable_symbol -> next = base[k];
  2053.     base[k] = variable_symbol;
  2054.  
  2055.     //
  2056.     // If the set is "adjustable" and the number of unique elements in it exceeds
  2057.     // 2 times the size of the base, and we have not yet reached the maximum
  2058.     // allowable size for a base, reallocate a larger base and rehash the elements.
  2059.     //
  2060.     if ((hash_size < MAX_HASH_SIZE) && (Size() > (hash_size << 1)))
  2061.         Rehash();
  2062.  
  2063.     return;
  2064. }
  2065.  
  2066.  
  2067. inline void TypeSymbol::InsertVariableSymbol(VariableSymbol *variable_symbol)
  2068. {
  2069.     Table() -> InsertVariableSymbol(variable_symbol);
  2070. }
  2071.  
  2072.  
  2073. inline void BlockSymbol::InsertVariableSymbol(VariableSymbol *variable_symbol)
  2074. {
  2075.     Table() -> InsertVariableSymbol(variable_symbol);
  2076. }
  2077.  
  2078.  
  2079. inline VariableSymbol *SymbolTable::FindVariableSymbol(NameSymbol *name_symbol)
  2080. {
  2081. assert(base);
  2082.     for (Symbol *symbol = base[name_symbol -> index % hash_size]; symbol; symbol = symbol -> next)
  2083.     {
  2084.         if (name_symbol == symbol -> Identity())
  2085.         {
  2086.             VariableSymbol *variable_symbol = symbol -> VariableCast();
  2087.             if (variable_symbol)
  2088.                 return variable_symbol;
  2089.         }
  2090.     }
  2091.  
  2092.     return (VariableSymbol *) NULL;
  2093. }
  2094.  
  2095.  
  2096. inline VariableSymbol *TypeSymbol::FindVariableSymbol(NameSymbol *name_symbol)
  2097. {
  2098.     return (table ? table -> FindVariableSymbol(name_symbol) : (VariableSymbol *) NULL);
  2099. }
  2100.  
  2101.  
  2102. inline VariableSymbol *BlockSymbol::FindVariableSymbol(NameSymbol *name_symbol)
  2103. {
  2104.     return (table ? table -> FindVariableSymbol(name_symbol) : (VariableSymbol *) NULL);
  2105. }
  2106.  
  2107.  
  2108. inline LabelSymbol *SymbolTable::InsertLabelSymbol(NameSymbol *name_symbol)
  2109. {
  2110. assert(base);
  2111.     LabelSymbol *symbol = new LabelSymbol(name_symbol);
  2112.     AddOtherSymbol(symbol);
  2113.  
  2114.     int k = name_symbol -> index % hash_size;
  2115.     symbol -> next = base[k];
  2116.     base[k] = symbol;
  2117.  
  2118.     //
  2119.     // as only one label can be inserted in any given symboltable,
  2120.     // we don't need to try to rehash here !
  2121.     //
  2122.  
  2123.     return symbol;
  2124. }
  2125.  
  2126.  
  2127. inline LabelSymbol *SymbolTable::FindLabelSymbol(NameSymbol *name_symbol)
  2128. {
  2129. assert(base);
  2130.     for (Symbol *symbol = base[name_symbol -> index % hash_size]; symbol; symbol = symbol -> next)
  2131.     {
  2132.         if (name_symbol == symbol -> Identity())
  2133.         {
  2134.             LabelSymbol *label = symbol -> LabelCast();
  2135.             if (label)
  2136.                 return label;
  2137.         }
  2138.     }
  2139.  
  2140.     return (LabelSymbol *) NULL;
  2141.  
  2142. inline BlockSymbol *SymbolTable::InsertBlockSymbol(int hash_size = 0)
  2143. {
  2144.     BlockSymbol *symbol = new BlockSymbol(hash_size);
  2145.     AddOtherSymbol(symbol);
  2146.  
  2147.     return symbol;
  2148. }
  2149.  
  2150.  
  2151. inline BlockSymbol *BlockSymbol::InsertBlockSymbol(int hash_size = 0)
  2152. {
  2153.     return Table() -> InsertBlockSymbol(hash_size);
  2154. }
  2155.  
  2156.  
  2157. inline MethodSymbol *SymbolTable::Overload(MethodSymbol *base_method)
  2158. {
  2159.     MethodSymbol *overload = new MethodSymbol(base_method -> Identity());
  2160.     AddMethodSymbol(overload);
  2161.  
  2162.     overload -> next = overload; // mark overloaded method
  2163.     overload -> next_method = base_method -> next_method;
  2164.     base_method -> next_method = overload;
  2165.  
  2166.     return overload;
  2167. }
  2168.  
  2169.  
  2170. inline MethodSymbol *TypeSymbol::Overload(MethodSymbol *base_method)
  2171. {
  2172. assert(table);
  2173.     return table -> Overload(base_method);
  2174. }
  2175.  
  2176.  
  2177. inline void SymbolTable::Overload(MethodSymbol *base_method, MethodSymbol *overload)
  2178. {
  2179.     AddMethodSymbol(overload);
  2180.  
  2181.     overload -> next = overload; // mark overloaded method
  2182.     overload -> next_method = base_method -> next_method;
  2183.     base_method -> next_method = overload;
  2184.  
  2185.     return;
  2186. }
  2187.  
  2188. inline void TypeSymbol::Overload(MethodSymbol *base_method, MethodSymbol *overload)
  2189. {
  2190. assert(table);
  2191.     table -> Overload(base_method, overload);
  2192. }
  2193.  
  2194.  
  2195. inline MethodSymbol *SymbolTable::LocalConstructorOverload(MethodSymbol *base_method)
  2196. {
  2197.     MethodSymbol *overload = new MethodSymbol(base_method -> Identity());
  2198.     AddMethodSymbol(overload);
  2199.  
  2200.     overload -> next = overload; // mark overloaded method
  2201.     overload -> SetGeneratedLocalConstructor(base_method);
  2202.  
  2203.     return overload;
  2204. }
  2205.  
  2206.  
  2207. inline MethodSymbol *TypeSymbol::LocalConstructorOverload(MethodSymbol *base_method)
  2208. {
  2209. assert(table);
  2210.     return table -> LocalConstructorOverload(base_method);
  2211. }
  2212.  
  2213.  
  2214. inline MethodSymbol *TypeSymbol::FindOverloadMethod(MethodSymbol *base_method, AstMethodDeclarator *method_declarator)
  2215. {
  2216.     return (table ? table -> FindOverloadMethod(base_method, method_declarator) : (MethodSymbol *) NULL);
  2217. }
  2218.  
  2219.  
  2220. inline SymbolTable *DirectorySymbol::Table()
  2221. {
  2222.     return (table ? table : table = new SymbolTable(101));
  2223. }
  2224.  
  2225. inline SymbolTable *PackageSymbol::Table()
  2226. {
  2227.     return (table ? table : table = new SymbolTable(101));
  2228. }
  2229.  
  2230. inline void TypeSymbol::SetSymbolTable(int estimate)
  2231. {
  2232.     if (! table) // If table was not yet allocated, allocate one based on the estimate
  2233.         table = new SymbolTable(estimate);
  2234. }
  2235.  
  2236. inline SymbolTable *TypeSymbol::Table()
  2237. {
  2238.     return (table ? table : table = new SymbolTable());
  2239. }
  2240.  
  2241. inline SymbolTable *BlockSymbol::Table()
  2242. {
  2243.     return (table ? table : table = new SymbolTable());
  2244. }
  2245.  
  2246. #ifdef UNIX_FILE_SYSTEM
  2247.     inline bool FileSymbol::IsClassSuffix(char *suffix)
  2248.     {
  2249.         return (strncmp(suffix, class_suffix, class_suffix_length) == 0);
  2250.     }
  2251.  
  2252.     inline bool  FileSymbol::IsJavaSuffix(char *suffix)
  2253.     {
  2254.         return (strncmp(suffix, java_suffix, java_suffix_length) == 0);
  2255.     }
  2256. #elif defined(WIN32_FILE_SYSTEM)
  2257.     inline bool FileSymbol::IsClassSuffix(char *suffix)
  2258.     {
  2259.         return Case::StringSegmentEqual(suffix, class_suffix, class_suffix_length);
  2260.     }
  2261.  
  2262.     inline bool  FileSymbol::IsJavaSuffix(char *suffix)
  2263.     {
  2264.         return Case::StringSegmentEqual(suffix, java_suffix, java_suffix_length);
  2265.     }
  2266. #elif defined(AMIGAOS_FILE_SYSTEM)
  2267.     // Do not use StringSegmentEqual() as in the WIN32 case, because that
  2268.     // function may check beyond the end of the string, thus possibly causing
  2269.     // enforcer hits.
  2270.     inline bool FileSymbol::IsClassSuffix(char *suffix)
  2271.     {
  2272.         return (strncasecmp(suffix, class_suffix, class_suffix_length) == 0);
  2273.     }
  2274.  
  2275.     inline bool  FileSymbol::IsJavaSuffix(char *suffix)
  2276.     {
  2277.         return (strncasecmp(suffix, java_suffix, java_suffix_length) == 0);
  2278.     }
  2279. #endif
  2280.  
  2281. #endif // ifndef symbol_INCLUDED
  2282.